package com.ynet.middleground.user.utils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.ifp.util.core.Md5;
import com.ynet.cache.redis.IfpRedisson;
import com.ynet.core.common.ServiceResult;
import com.ynet.middleground.user.common.SystemConstant;
import com.ynet.middleground.user.dao.SystemParametersMapper;
import com.ynet.middleground.user.entity.EnterpriseBasicInfo;
import com.ynet.middleground.user.entity.SystemParameters;
import com.ynet.middleground.user.entity.UserBaseInformation;

/**
 * 用户中心工具类
 * 
 * @author DaiGaoLe 2019-10-15
 */
@Component
public class CommUtils {

    @Autowired
    public IfpRedisson redisson;

    @Autowired
    public SystemParametersMapper systemParametersMapper;

    /**
     * 获取用户唯一id DaiGaoLe 2019-10-15
     * 
     * @param channel 渠道编号
     */
    public static String getUserId(String channel) {
        UniqueOrderGenerate uniqueOrderGenerate = new UniqueOrderGenerate(0, 0);
        // 返回为18位数字
        long id = uniqueOrderGenerate.nextId();
        // 返回为20位用户唯一id
        return channel + Long.toString(id);
    }

    /**
     * DaiGaoLe
     *
     * @author DaiGaoLe 2019-10-15 获取唯一邀请码(2019-10-14:暂时只有青港易付平台使用)
     */
    public static String getInviteCode() {
        RandomId randomId = new RandomId();
        String inviteCode = randomId.randomId();
        return inviteCode;
    }

    /**
     * DaiGaoLe
     *
     * @author DaiGaoLe 2019-10-15 获取唯一码
     */
    public static String getRandomId() {
        RandomId randomId = new RandomId();
        String inviteCode = randomId.randomId();
        return inviteCode;
    }

    /**
     * @author DaiGaoLe 2019-10-15 获取4位数盐的随机数
     */
    public static String getSalt() {
        return getInviteCode().substring(0, 4);
    }

    /**
     * @author DaiGaoLe 2019-10-16 获取ServiceResult对象
     */
    public static ServiceResult<?> getServiceResult(Object t) {
        if (t instanceof String) {
            return new ServiceResult<String>();
        }
        if (t instanceof List) {
            return new ServiceResult<List>();
        }
        if (t instanceof Map) {
            return new ServiceResult<Map>();
        }
        return null;

    }

    /**
     * @author DaiGaoLe 2019-10-17 获取ServiceResult对象
     */
    public static void initServiceResult(ServiceResult serviceResult) {
        // serviceResult.setError ( SystemConstant.ERROR_CODE_0000 ,SystemConstant.ERROR_MSG_SUCCESS);
        serviceResult.setSuccess(true);
    }

    /**
     * @author DaiGaoLe 2019-10-16 获取ServiceResult对象
     */
    public static Map<String, Object> getMap() {
        return new HashMap<String, Object>();
    }

    /**
     * @author DaiGaoLe 2019-10-16 校验账号是否重复
     */
    public static boolean verifyTheCheckAccountIsRepeated(String account) {
        // getUserAccounts
        return false;
    }

    /**
     * @author DaiGaoLe 2019-10-16 判断是否为空，如果是空返回true,反之返回false
     */
    public static boolean objectIsNull(Object object) {
        if (object == null) {
            return true;
        }
        return false;
    }

    /**
     * @author DaiGaoLe 2019-10-16
     * @Title: 去空格
     * @Description: 去空格
     * @param str
     * @return string
     */
    public static String trim(String str) {
        if (str == null) {
            return "";
        }

        return str.trim();
    }

    /**
     * @category 获取EnterpriseBasicInfo对象
     * @author DaiGaoLe 2019年10月18日, AM 02:58:59
     * @return
     */
    public static EnterpriseBasicInfo getEnterpriseBasicInfo() {
        return new EnterpriseBasicInfo();
    }

    /**
     * @category 获取UserBaseInformation对象
     * @author DaiGaoLe 2019年10月18日, AM 02:58:59
     * @return
     */
    public static UserBaseInformation getUserBaseInformation() {
        return new UserBaseInformation();
    }

    //
    /**
     * 取得时间戳
     *
     * @return 时间戳
     */
    public static Timestamp getTimestamp() {
        return new Timestamp(System.currentTimeMillis());
    }

    /**
     * 返回yyyy-MM-dd格式的字符串
     *
     * @author DaiGaoLe
     * @Date 2019-10-17
     * @param date
     * @return
     */
    public static String dateToString(java.util.Date date) {
        if (date == null) {
            return null;
        }

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(SystemConstant.DATE_PATTERN);
        return simpleDateFormat.format(date);
    }

    /**
     * 校验日期格式
     * 
     * @param dateStr
     * @return
     */
    public static boolean validDateStr(String dateStr, String pattern) {
        if (StringUtils.isEmpty(pattern)) {
            pattern = "yyyy-MM-dd";
        }
        try {
            LocalDate.parse(dateStr, new DateTimeFormatterBuilder().appendPattern(pattern).parseStrict().toFormatter());
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 由日期返回yyyyMMdd格式的字符串
     *
     * @author DaiGaoLe
     * @Date 2019-10-17
     * @param date
     * @return
     */
    public static String dateToNumber(Date date) {
        if (date == null) {
            return null;
        }

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(SystemConstant.DATE_NUMBER_PATTERN);
        return simpleDateFormat.format(date);
    }

    /**
     * 由yyyy-MM-dd格式的字符串返回日期 java.util.Date
     *
     * @author DaiGaoLe
     * @Date 2019-10-17
     * @return
     * @throws java.text.ParseException
     */
    public static Date stringToDate(String string) throws ParseException, java.text.ParseException {
        if (string == null) {
            return null;
        }

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(SystemConstant.DATE_PATTERN);

        return simpleDateFormat.parse(string);
    }

    /**
     * 由yyyy-MM-dd格式的字符串返回日期 java.sql.Date
     *
     * @author DaiGaoLe
     * @Date 2019-10-17
     * @return
     * @throws java.text.ParseException
     */
    public static java.sql.Date stringToSqlDate(String string) throws ParseException, java.text.ParseException {
        if (string == null) {
            return null;
        }

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(SystemConstant.DATE_PATTERN);

        return new java.sql.Date(simpleDateFormat.parse(string).getTime());
    }

    /**
     * 由yyyyMMdd格式的字符串返回日期 java.util.Date
     *
     * @author DaiGaoLe
     * @Date 2019-10-17
     * @return
     * @throws java.text.ParseException
     */
    public static Date numberToDate(String string) throws ParseException, java.text.ParseException {
        if (string == null) {
            return null;
        }

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(SystemConstant.DATE_NUMBER_PATTERN);
        return simpleDateFormat.parse(string);
    }

    /**
     * 由yyyyMMdd格式的字符串返回日期 java.sql.Date
     *
     * @author DaiGaoLe
     * @Date 2019-10-17
     * @return
     * @throws java.text.ParseException
     */
    public static java.sql.Date numberToSqlDate(String string) throws ParseException, java.text.ParseException {
        if (string == null) {
            return null;
        }

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(SystemConstant.DATE_NUMBER_PATTERN);
        return new java.sql.Date(simpleDateFormat.parse(string).getTime());
    }

    /**
     * 由日期返回yyyyMM格式
     *
     * @author DaiGaoLe
     * @Date 2019-10-17
     * @param time
     * @return
     */
    public static String dateToYearMonth(Date time) {
        if (time == null) {
            return null;
        }

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(SystemConstant.YEAR_MONTH_PATTERN);
        return simpleDateFormat.format(time);
    }

    /**
     * 由日期返回yyyy-MM-dd HH:mm:ss格式的字符串
     *
     * @author DaiGaoLe
     * @Date 2019-10-17
     * @param time
     * @return
     */
    public static String timeToString(Date time) {
        if (time == null) {
            return null;
        }

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(SystemConstant.TIME_PATTERN);
        return simpleDateFormat.format(time);
    }

    /**
     * 由日期返回yyyyMMddHHmmss格式的字符串
     *
     * @author DaiGaoLe
     * @Date 2019-10-17
     * @param time
     * @return
     */
    public static String timeToNumber(Date time) {
        if (time == null) {
            return null;
        }

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(SystemConstant.FULL_DATE_NUMBER);
        return simpleDateFormat.format(time);
    }

    /**
     * 由日期返回yyyy-MM-dd-HH.mm.ss.SSSSSS格式的字符串
     *
     * @author DaiGaoLe
     * @Date 2019-10-17
     * @param date Date格式日期
     * @return String yyyy-MM-dd-HH.mm.ss.SSSSSS格式 的字符串
     */
    public static String getTimeStampFormat(Date date) {
        if (date == null) {
            return null;
        }

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(SystemConstant.FULL_TIME);
        return simpleDateFormat.format(date);
    }

    /**
     * 计算两个日期相隔的天数
     *
     * @author DaiGaoLe
     * @Date 2019-10-17
     * @param startDate
     * @param endDate
     * @return
     */
    public static int getDaysBetween(Date startDate, Date endDate) {
        Calendar calendarStartDate = Calendar.getInstance();
        Calendar calendarEndDate = Calendar.getInstance();

        // 设日历为相应日期
        calendarStartDate.setTime(startDate);
        calendarEndDate.setTime(endDate);
        if (startDate.after(endDate)) {
            Calendar swap = calendarStartDate;
            calendarStartDate = calendarEndDate;
            calendarEndDate = swap;
        }

        int days = calendarEndDate.get(Calendar.DAY_OF_YEAR) - calendarStartDate.get(Calendar.DAY_OF_YEAR);
        int y2 = calendarEndDate.get(Calendar.YEAR);
        while (calendarStartDate.get(Calendar.YEAR) < y2) {
            days += calendarStartDate.getActualMaximum(Calendar.DAY_OF_YEAR);
            calendarStartDate.add(Calendar.YEAR, 1);
        }

        return days;
    }

    /**
     * @Description: localDateTimeToString 转字符串 yyyy-MM-dd HH:mm:ss
     * @Param: localDateTime
     * @return: String
     * @Author: DaiGaoLe
     * @Date: 2019/10/19
     */
    public static String localDateTimeToString(LocalDateTime localDateTime) {
        return localDateTime.format(DateTimeFormatter.ofPattern(SystemConstant.TIME_PATTERN));
    }

    public static LocalDateTime addDateDay(LocalDateTime localDateTime, String day) {
        return localDateTime.plusDays(Long.parseLong(day));
    }

    /**
     * 判断date是否为空
     *
     * @author DaiGaoLe
     * @Date 2019-10-17
     * @param date
     * @return 如果为空则返回true，否则返回true
     */
    public static boolean isEmpty(Date date) {
        if (date == null || "1900-01-01".equals(dateToString(date))) {
            return true;
        } else {
            return false;
        }
    }

    //
    /**
     * 生成标准rediskey 公司框架名称:表前缀:字段名:唯一主键
     */
    public static String getRedisKey(String tablesName, String fieldName, String id) {
        // 公司框架名称:表前缀:字段名:唯一主键 ifp:uc:channel:channellist
        return SystemConstant.FRAMEWORK_NAME + ":" + tablesName + ":" + fieldName + ":" + id;
    }

    /**
     * 生成 RedisKey
     *
     * @param suffix key 的后部分
     * @return 完整 key
     * @author liulx
     * @date 2020-07-13 09:25:10
     */
    public static String getRedisKey(String suffix) {
        return SystemConstant.FRAMEWORK_NAME + ":channel:" + suffix;
    }

    /**
     * @Description:
     * @Param: password 没有加密的密码，salt 盐
     * @return: MD5加盐后的密码串
     * @Author: DaiGaoLe
     * @Date: 2019/10/20
     */
    public static String getMd5SaltPassword(String password, String salt) {
        return Md5.getMD5SaltPassword(password, salt);
    }

    /**
     * @Description:
     * @Param: password 密码
     * @return: MD5加密的密码串
     * @Author: DaiGaoLe
     * @Date: 2019/10/20
     */
    public static String getMs5Password(String password) {
        return Md5.getMd5String(password);
    }

    /**
     * @Description:
     * @Param:
     * @return:
     * @Author: DaiGaoLe
     * @Date: 2019/10/19
     */
    public String getSystemParameterValueOne(String code, String name) {
        Map<String, Object> parameterMap = new HashMap<String, Object>();
        parameterMap.put("code", code);
        parameterMap.put("name", name);
        List<SystemParameters> systemParameters = systemParametersMapper.selectByMap(parameterMap);
        SystemParameters systemParameters1 = systemParameters.get(0);
        return systemParameters1.getValue();
    }

    public static void isNotNullSetValue(Class classObject, String value, String name) {
        try {
            Method method = classObject.getMethod(name, String.class);
            if (StringUtils.isNotEmpty(value)) {
                method.invoke(name, value);
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    /**
     * @Description: 校验手机号是否符合规则
     * @Param: phone 手机号
     * @return: boolean
     * @Author: DaiGaoLe
     * @Date: 2019/10/21
     */
    public static boolean isPhone(String phone) {
        /* String regex =
            "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$";*/
        String regex = "^1[\\d]{10}";
        boolean isAccord = false;
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(phone);
        if (phone.length() == SystemConstant.PHONE_NUMBER_LENGTH && m.matches()) {
            isAccord = true;
        }
        return isAccord;
    }

    /**
     * 只允许字母数字，以及英文逗号
     * 
     * @param available_channel
     * @return
     */
    public static boolean checkChannel(String available_channel) {
        String regex = "^[a-zA-Z0-9,]+$";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(available_channel);
        if (m.matches()) {
            return true;
        }
        return false;
    }

    /**
     * @Description: 正则验证邮箱
     * @Param: email 邮箱地址
     * @return: boolean
     * @Author: DaiGaoLe
     * @Date: 2019/10/21
     */
    public static boolean isEmail(String email) {
        if (null == email || "".equals(email)) {
            return false;
        }
        String regEx1 = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
        Pattern p = Pattern.compile(regEx1);
        Matcher m = p.matcher(email);
        if (m.matches()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * @Description: 身份证号码正则表达式校验
     * @Param: IdNumber 身份证号
     * @return: boolean
     * @Author: DaiGaoLe
     * @Date: 2019/10/21
     */
    public static boolean isIdNumber(String IdNumber) {
        if (IdNumber == null || "".equals(IdNumber)) {
            return false;
        }
        // 定义判别用户身份证号的正则表达式（15位或者18位，最后一位可以为字母）
        String regularExpression =
            "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|"
                + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)";
        // 假设18位身份证号码:41000119910101123X 410001 19910101 123X
        // ^开头
        // [1-9] 第一位1-9中的一个 4
        // \\d{5} 五位数字 10001（前六位省市县地区）
        // (18|19|20) 19（现阶段可能取值范围18xx-20xx年）
        // \\d{2} 91（年份）
        // ((0[1-9])|(10|11|12)) 01（月份）
        // (([0-2][1-9])|10|20|30|31)01（日期）
        // \\d{3} 三位数字 123（第十七位奇数代表男，偶数代表女）
        // [0-9Xx] 0123456789Xx其中的一个 X（第十八位为校验值）
        // $结尾

        // 假设15位身份证号码:410001910101123 410001 910101 123
        // ^开头
        // [1-9] 第一位1-9中的一个 4
        // \\d{5} 五位数字 10001（前六位省市县地区）
        // \\d{2} 91（年份）
        // ((0[1-9])|(10|11|12)) 01（月份）
        // (([0-2][1-9])|10|20|30|31)01（日期）
        // \\d{3} 三位数字 123（第十五位奇数代表男，偶数代表女），15位身份证不含X
        // $结尾

        boolean matches = IdNumber.matches(regularExpression);

        // 判断第18位校验值
        if (matches) {

            if (IdNumber.length() == 18) {
                try {
                    char[] charArray = IdNumber.toCharArray();
                    // 前十七位加权因子
                    int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
                    // 这是除以11后，可能产生的11位余数对应的验证码
                    String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
                    int sum = 0;
                    for (int i = 0; i < idCardWi.length; i++) {
                        int current = Integer.parseInt(String.valueOf(charArray[i]));
                        int count = current * idCardWi[i];
                        sum += count;
                    }
                    char idCardLast = charArray[17];
                    int idCardMod = sum % 11;
                    if (idCardY[idCardMod].toUpperCase().equals(String.valueOf(idCardLast).toUpperCase())) {
                        return true;
                    } else {
                        return false;
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                }
            }

        }
        return matches;
    }

    /**
     * @Description: 密码必须是包含大写字母、小写字母、数字、特殊符号（不是字母，数字，下划线，汉字的字符）的8位以上组合
     * @Param: password 密码
     * @return: boolean
     * @Author: DaiGaoLe
     * @Date: 2019/10/21
     */
    public static boolean checkPassword(String password) {
        Pattern Password_Pattern = Pattern.compile(SystemConstant.PW_PATTERN);
        Matcher matcher = Password_Pattern.matcher(password);
        if (matcher.matches()) {
            return true;
        }
        return false;
    }

    /**
     * @Description: 判断两个用户id是否是同一id
     * @Param: userId1,userId2
     * @return: boolean
     * @Author: DaiGaoLe
     * @Date: 2019/10/22
     */
    public static boolean isSameUserId(String userId1, String userId2) {
        boolean equals = false;
        if (userId1 != null && userId2 != null) {
            equals = userId1.equals(userId2);
        }
        return equals;
    }

    public static String isSameUserIdReturnString(String userId1, String userId2) {
        String equals = SystemConstant.SYSTEM_SUCCESS;
        if (userId1 != null && userId2 != null && userId1.equals(userId2)) {
            equals = "操作员id和用户id相同";
        }
        return equals;
    }

    // 1、map转换为object

    public static Object mapToObject(Map<String, Object> map, Class<?> beanClass) throws Exception {
        if (map == null) {
            return null;

        }
        Object obj = beanClass.newInstance();
        org.apache.commons.beanutils.BeanUtils.populate(obj, map);
        return obj;
    }

    public static Object mapToObjectTString(Map<String, String> map, Class<?> beanClass) throws Exception {
        if (map == null) {
            return null;

        }
        Object obj = beanClass.newInstance();
        org.apache.commons.beanutils.BeanUtils.populate(obj, map);
        return obj;
    }
    // 2、object转换为map

    public static Map<?, ?> objectToMap(Object obj) {
        if (obj == null) {
            return null;
        }
        return new org.apache.commons.beanutils.BeanMap(obj);
    }
}
